fix(schedule): preserve scroll position when returning from a session - #190
Merged
Conversation
The schedule grid's per-day scroll positions were held in a plain `remember`. Navigation Compose tears the schedule destination out of composition when opening a session detail, so on back-navigation the `LazyGridState`s were recreated at offset 0 and the list jumped to the top. Hold them in `rememberSaveable` with a `listSaver` that persists each day's first-visible index and offset, so they survive the composition tear-down via the NavBackStackEntry's saveable state. The restore clamps the list to the current day count to keep `gridStates[page]` indexing safe if the agenda changes while away. Adds the `compose.runtimeSaveable` dependency, needed to import `rememberSaveable`/`listSaver` directly. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In the Android app's schedule screen, scrolling through the agenda, opening a session, and pressing back reset the scroll position to the top. The selected day was kept, but the scroll within the day was lost — forcing the user to scroll back down every time.
Root cause
Navigation Compose only composes the top destination. When you open a session detail, the
ScheduleListdestination leaves composition (itsNavBackStackEntrystays on the back stack, but the composable tree is torn down). OnpopBackStack()it's composed fresh.The per-day scroll states in
ScheduleGridPagerwere held in a plainremember:Plain
rememberis discarded on tear-down, so the states came back as brand-newLazyGridState()instances at offset 0. The pager state survived becauserememberPagerStateis saveable — which is exactly why the day was preserved but the scroll wasn't.Fix
Hold the grid states in
rememberSaveablewith alistSaverthat persists each day'sfirstVisibleItemIndex+firstVisibleItemScrollOffset, plugging into the sameSaveableStateHoldermechanism the back-stack entry uses. Saving the whole list under a single key avoids the per-iteration key-collision trap you'd hit building a list ofrememberLazyGridState()calls in a loop.The restore clamps the list to the current day count, so a changed agenda day-count can't cause an
IndexOutOfBoundsongridStates[page].Also adds the
compose.runtimeSaveabledependency — the module previously only used the foundation wrappers, soandroidx.compose.runtime.saveablewasn't on its compile classpath.Testing
ktlintCheck+detekt✅:androidApp:lintDebug✅remember→rememberSaveablefix, but a quick manual pass (scroll → open session → back) would confirm.🤖 Generated with Claude Code